#include "MainWindow.h"

#include <QHBoxLayout>
#include <QPaintEvent>
#include <QPainter>

#ifdef Q_OS_LINUX
const QString TrayThemeIconPath = "WebdavClient";
const QList<QString> SyncingAniThemeIconPathList = {
    "WebdavClientSyncing1",
    "WebdavClientSyncing2",
    "WebdavClientSyncing3"
};
#elif defined Q_OS_WIN
const QString TrayThemeIconPath = ":/Icons/WebdavClient.svg";
const QList<QString> SyncingAniThemeIconPathList = {
    ":/Ani/WebdavClientSyncing1.png",
    ":/Ani/WebdavClientSyncing2.png",
    ":/Ani/WebdavClientSyncing3.png"
};
#endif

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , m_model(new Model(this))
    , m_busyWorkerCount(0)
    , m_itemTableView(nullptr)
    , m_itemTableViewModel(nullptr)
    , m_sysTray(nullptr)
    , m_trayAniTimer(nullptr)
    , m_currentAniIndex(0)
{
    QWidget *contentWidget = new QWidget(this);
    setCentralWidget(contentWidget);

    QVBoxLayout *contentLayout = new QVBoxLayout(contentWidget);
    contentLayout->setContentsMargins(5, 5, 5, 5);

    contentLayout->addSpacing(5);
    QHBoxLayout *contentTitelLayout = new QHBoxLayout;
    contentTitelLayout->setContentsMargins(0, 0, 0, 0);
    contentTitelLayout->setSpacing(0);
    contentLayout->addLayout(contentTitelLayout);

    QLabel *contentTitleLabel = new QLabel(this);
    contentTitleLabel->setText("同步列表");
    contentTitelLayout->addWidget(contentTitleLabel, 1, Qt::AlignLeft | Qt::AlignVCenter);

    QPushButton *itemModifyBtn = new QPushButton(this);
    itemModifyBtn->setFixedSize(24, 24);
    itemModifyBtn->setIcon(QIcon(":/Icons/Modify.svg"));
    contentTitelLayout->addWidget(itemModifyBtn, 0, Qt::AlignRight | Qt::AlignVCenter);

    contentTitelLayout->addSpacing(5);
    QPushButton *itemAddBtn = new QPushButton(this);
    itemAddBtn->setFixedSize(24, 24);
    itemAddBtn->setText("+");
    contentTitelLayout->addWidget(itemAddBtn, 0, Qt::AlignRight | Qt::AlignVCenter);

    contentTitelLayout->addSpacing(5);
    QPushButton *itemDeleteBtn = new QPushButton(this);
    itemDeleteBtn->setFixedSize(24, 24);
    itemDeleteBtn->setText("-");
    contentTitelLayout->addWidget(itemDeleteBtn, 0, Qt::AlignRight | Qt::AlignVCenter);

    contentLayout->addSpacing(5);
    m_itemTableView = new QTableView(this);
    m_itemTableView->setIconSize(QSize(30, 30));
    m_itemTableView->setEditTriggers(QTableView::EditTrigger::NoEditTriggers);
    //    itemTreeView->setStyleSheet("background-color:yellow");
    m_itemTableView->setTextElideMode(Qt::TextElideMode::ElideMiddle);
    m_itemTableView->setWordWrap(false);
    m_itemTableView->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
    m_itemTableView->setAlternatingRowColors(true);
    m_itemTableView->verticalHeader()->setVisible(false);
    m_itemTableView->horizontalHeader()->setStretchLastSection(true);
    contentLayout->addWidget(m_itemTableView, 1);

    m_itemTableViewModel = new QStandardItemModel(this);
    m_itemTableView->setModel(m_itemTableViewModel);

    const QList<QString> headerStrList = {
        "序号",
        "本地目录",
        "远程目录",
        "状态"
    };
    m_itemTableViewModel->setHorizontalHeaderLabels(headerStrList);
    QTimer::singleShot(1, this, [this] {
        int snColWidth = 50;
        int stateColWidth = 100;
        m_itemTableView->horizontalHeader()->resizeSection(0, snColWidth);
        int w = m_itemTableView->viewport()->width();
        int sectionSize = (w - snColWidth - stateColWidth) / 2;
        m_itemTableView->horizontalHeader()->resizeSection(1, sectionSize);
        m_itemTableView->horizontalHeader()->resizeSection(2, sectionSize);
        m_itemTableView->horizontalHeader()->resizeSection(3, stateColWidth);
    });

    // sys tray
    m_sysTray = new QSystemTrayIcon(this);
    m_sysTray->setIcon(QIcon::fromTheme(TrayThemeIconPath));

    QMenu *m_sysTrayMenu = new QMenu(this);
    m_sysTray->setContextMenu(m_sysTrayMenu);

    QAction *quitAction = new QAction(this);
    quitAction->setText("退出");
    m_sysTrayMenu->addAction(quitAction);
    m_sysTray->show();

    m_trayAniTimer = new QTimer(this);
    m_trayAniTimer->setInterval(500);

    // connection
    connect(itemModifyBtn, &QPushButton::clicked, this, [this]{
        int cfgIndex = m_itemTableView->currentIndex().row();
        if (cfgIndex < 0) {
            return;
        }

        WorkerModel::WebdavCfg cfg = m_model->GetWebdavCfg(cfgIndex);
        ItemModifyDlg dlg(cfg);
        dlg.show();
        int ret = dlg.exec();
        if (ret == 1) {
            cfg = dlg.GetCfg();
            m_model->AsyncSetWebdavCfg(cfgIndex, cfg);
        }
    });
    connect(itemAddBtn, &QPushButton::clicked, this, [this]{
        WorkerModel::WebdavCfg cfg;
        ItemModifyDlg dlg(cfg);
        dlg.show();
        int ret = dlg.exec();
        if (ret == 1) {
            cfg = dlg.GetCfg();
            m_model->AddWorker(cfg);
            addItem(cfg);
        }
    });
    connect(itemDeleteBtn, &QPushButton::clicked, this, [this]{
        int cfgIndex = m_itemTableView->currentIndex().row();
        if (cfgIndex < 0) {
            return;
        }
        const QString &msg = QString("是否确认删除配置[%1]").arg(cfgIndex + 1);
        QMessageBox::StandardButtons ret = QMessageBox::warning(nullptr, "注意", msg,
                             QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::Cancel);
        if (ret == QMessageBox::StandardButton::Yes) {
            m_model->RemoveWorker(cfgIndex);
            removeItem(cfgIndex);
        }
    });

    connect(m_model, &Model::SetWebdavCfgFinished, this, &MainWindow::OnSetWebdavCfgFinished);
    connect(m_model, &Model::WorkerStateChanged, this, &MainWindow::OnWorkerStateChanged);
    // tray
    connect(m_sysTray, &QSystemTrayIcon::activated, this, [=](QSystemTrayIcon::ActivationReason reason) {
        if (reason == QSystemTrayIcon::ActivationReason::Trigger) {
            this->hide();
            this->showNormal();
            this->activateWindow();
        }
    });
    connect(quitAction, &QAction::triggered, this, [=] {
        qApp->exit();
    });
    connect(m_trayAniTimer, &QTimer::timeout, this, &MainWindow::onAniTimerTimeout);

    // post init
    for (int i = 0; i < m_model->GetWebdavCfgCount(); i++) {
        const WorkerModel::WebdavCfg &cfg = m_model->GetWebdavCfg(i);
        addItem(cfg);
    }

    m_itemTableView->setCurrentIndex(m_itemTableViewModel->index(0, 0));
}

MainWindow::~MainWindow()
{
}

void MainWindow::OnSetWebdavCfgFinished(int workerIndex, bool succeed, const WorkerModel::WebdavCfg &cfg)
{
    if (!succeed) {
        return;
    }
    QStandardItem *localPathItem = m_itemTableViewModel->item(workerIndex, 1);
    localPathItem->setText(cfg.LocalDirPath);
    QStandardItem *remotePathItem = m_itemTableViewModel->item(workerIndex, 2);
    remotePathItem->setText(cfg.RemoteDirPath);
}

void MainWindow::OnWorkerStateChanged(int workerIndex, WorkerModel::State s)
{
    QStandardItem *stateItem = m_itemTableViewModel->item(workerIndex, 3);
    if (s == WorkerModel::Normal) {
        m_busyWorkerCount--;
        stateItem->setText("空闲");
        m_sysTray->showMessage("", "同步完成", QSystemTrayIcon::Information, 3000);
    } else {
        m_busyWorkerCount++;
        stateItem->setText("同步中");
    }

    if (m_busyWorkerCount < 0) {
        m_busyWorkerCount = 0;
    }

    // ani
    if (m_busyWorkerCount > 0) {
        playTrayAni();
    } else {
        stopTrayAni();
    }
}

void MainWindow::onAniTimerTimeout()
{
    const QString &themeIconPath = SyncingAniThemeIconPathList[m_currentAniIndex];
    m_sysTray->setIcon(QIcon::fromTheme(themeIconPath));

    if (++m_currentAniIndex > 2) {
        m_currentAniIndex = 0;
    }
}

void MainWindow::closeEvent(QCloseEvent *e)
{
    e->ignore();
    hide();
}

void MainWindow::addItem(const WorkerModel::WebdavCfg &cfg)
{
    QStandardItem *snItem = new QStandardItem;
    snItem->setTextAlignment(Qt::AlignCenter);
    QStandardItem *localPathItem = new QStandardItem(cfg.LocalDirPath);
    QStandardItem *remotePathItem = new QStandardItem(cfg.RemoteDirPath);
    QStandardItem *statusItem = new QStandardItem;
    statusItem->setText("空闲");
    statusItem->setTextAlignment(Qt::AlignCenter);
    m_itemTableViewModel->appendRow({snItem, localPathItem, remotePathItem, statusItem});

    // reset sn
    for (int i = 0; i < m_itemTableViewModel->rowCount(); i++) {
        QStandardItem *snItem = m_itemTableViewModel->item(i, 0);
        snItem->setText(QString::number(i + 1));
    }
}

void MainWindow::removeItem(int index)
{
    m_itemTableViewModel->removeRow(index);

    // reset sn
    for (int i = 0; i < m_itemTableViewModel->rowCount(); i++) {
        QStandardItem *snItem = m_itemTableViewModel->item(i, 0);
        snItem->setText(QString::number(i + 1));
    }
}

void MainWindow::playTrayAni()
{
    m_currentAniIndex = 0;
    onAniTimerTimeout();
    m_trayAniTimer->start();
}

void MainWindow::stopTrayAni()
{
    m_trayAniTimer->stop();
    m_sysTray->setIcon(QIcon::fromTheme(TrayThemeIconPath));
}
